using System;
using System.IO;
using TFlex.Model;
using TFlex.Model.Model3D.Geometry;

namespace External3D
{
	// Abstract class for centrally symmetric objects. Stores the center of symmetry
	//
	// Абстрактный класс тел со свойством центральной симметрии. Хранит центр симметрии
	public abstract class CentralSymmetry : TFlex.Model.Model3D.ProxyOperation
	{
		protected const int FormatVersion = 0;

		// Center of symmetry
		//
		// Центр симметрии
		protected Point3D m_centre = new Point3D(0.0, 0.0, 0.0);
		public Point3D Centre
		{
			get { return m_centre; }
			set { m_centre = value; }
		}

		// Constructs a centrally symmetric object
		//
		// Конструирует новое тело со свойством центральной симметрии
		protected CentralSymmetry()
		{
		}

		// Constructs a centrally symmetric object. This constructor is used when the object is being created by the
		// External3D.External3DPlugin.CreateObject(TFlex.Model.Document, IntPtr, int) method
		//
		// Конструирует новое тело со свойством центральной симметрии. Вызывается при создании объекта с помощью метода
		// External3D.External3DPlugin.CreateObject(TFlex.Model.Document, IntPtr, int)
		protected CentralSymmetry(IntPtr ownerHandle)
			: base(ownerHandle)
		{
		}

		// Creates and returns a copy of this object. This method is called by the
		// TFlex.Model.Model3D.ExternalOperation.ExternalOperation(TFlex.Model.Model3D.ProxyOperation,
		//                                                         TFlex.Model.Document,
		//                                                         TFlex.Plugin)
		// constructor
		//
		// Возвращает копию объекта. Вызывается из конструктора
		// TFlex.Model.Model3D.ExternalOperation.ExternalOperation(TFlex.Model.Model3D.ProxyOperation,
		//                                                         TFlex.Model.Document,
		//                                                         TFlex.Plugin)
		protected override ProxyObject Clone(IntPtr ownerHandle)
		{
			CentralSymmetry clone = (CentralSymmetry)base.Clone(ownerHandle);
			clone.Centre = new Point3D(m_centre);

			return clone;
		}

		// Determines whether this object is equal to 'obj' or not
		//
		// Определяет, равен этот объект объекту 'obj' или нет
		protected override bool Equals(TFlex.Model.ProxyObject obj)
		{
			if (obj == this)
				return true;

			CentralSymmetry other = obj as CentralSymmetry;
			return other != null && m_centre != other.m_centre;
		}

		// Reads parameters of this object from the specified stream
		//
		// Чтение данных
		protected override void Read(Stream stream, int version)
		{
			base.Read(stream, version);

			BinaryReader reader = new BinaryReader(stream);
			m_centre.X = reader.ReadDouble();
			m_centre.Y = reader.ReadDouble();
			m_centre.Z = reader.ReadDouble();
		}

		// Saves parameters of this object to the specified stream
		//
		// Запись данных
		protected override void Write(Stream stream)
		{
			base.Write(stream);

			BinaryWriter writer = new BinaryWriter(stream);
			writer.Write(m_centre.X);
			writer.Write(m_centre.Y);
			writer.Write(m_centre.Z);
		}
	};
}
